﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TVGuide.DataAccess.Common;
using TVGuide.DataAccess.Exceptions;

namespace TVGuide.DataAccess.Repository
{
    public class LanguageRepository: ILanguageRepository
    {
        #region Singleton pattern

        private static tvchanneldbEntities model;
        private static LanguageRepository instance;

        private LanguageRepository() 
        {
            model = new tvchanneldbEntities();
            maxId = model.languages.Count();
        }

        public static LanguageRepository Instance()
        {
            if (instance == null)
                instance = new LanguageRepository();
            return instance;
        }

        #endregion

        #region IRepository<Language> Members

        public void Add(Language item)
        {
            Add(item, true);
        }

        public void Add(Language item, bool commitChange)
        {
            if (item == null)
                throw new InvalidArgsException("The parameter is null");

            if (String.IsNullOrEmpty(item.Name))
                throw new InvalidArgsException("The 'languageName' field is null");

            if (maxId == 0)
                item.Id = 1;
            else
            {
                item.Id = (short)++maxId;
            }

            model.languages.AddObject((language)item);

            if(commitChange)
                model.SaveChanges();
        }

        public void AddRange(IEnumerable<Language> items)
        {
            try
            {
                foreach (var item in items)
                {
                    Add(item, false);
                }
            }
            catch (InvalidArgsException e)
            {
                // TODO rollback changes.
                InvalidArgsException ex = new InvalidArgsException(e.Message + "\nNo items were committed.");
                throw ex;
            }
            model.SaveChanges();
        }

        public Language Get(int id)
        {
            return (Language)model.languages.FirstOrDefault(o => o.languageID == id);
        }

        public IEnumerable<Language> Get(Predicate<Language> func)
        {
            List<Language> list = new List<Language>();
            foreach (var item in model.languages)
            {
                Language cloneObj = (Language)item;
                if (func((Language)item))
                    list.Add(cloneObj);
            }
            return list;
        }

        public IEnumerable<Language> GetAllItems()
        {
            return Get(o => true);
        }

        public void Remove(int id)
        {
            language l = model.languages.FirstOrDefault(o => o.languageID == id);
            if (l != null)
                model.languages.DeleteObject(l);
            model.SaveChanges();
        }

        public void Remove(Predicate<Language> func)
        {
            List<language> removeList = new List<language>();
            foreach (var item in model.languages)
            {
                if (func((Language)item))
                    removeList.Add(item);
            }
            foreach (var item in removeList)
            {
                model.languages.DeleteObject(item);
            }
            model.SaveChanges();
        }

        public void RemoveAll()
        {
            Remove(o => true);
        }

        #endregion

        private int maxId;

    }
}
